/**
 * chessboard_internals.js - Javascript chess library
 *
 * http://code.google.com/p/fics-meets-html5/
 *
 * Copyright 2012 Markus Kupke
 */

var chesslib = chesslib || {};
 
chesslib.board = {}; //namespace for functions around the board
chesslib.board.boards = [];  //nodes that hold chessboards
chesslib.board.images = {};
chesslib.board.images.empty = ""; 
chesslib.board.images.emptyImageTag = document.createElement("IMG");
//this empty image is taken from http://commons.wikimedia.org/wiki/File:Tv_blank.svg
chesslib.board.images.emptyImageTag.setAttribute("src", chesslib.board.images.empty);
chesslib.board.images.emptyImageTag.style.width = "100%";

chesslib.board.images.pwSrc = 'mimes/BlackPawnWhiteField.svg'; 
chesslib.board.images.pbSrc = 'mimes/BlackPawnBlackField.svg'; 
chesslib.board.images.PwSrc = 'mimes/WhitePawnWhiteField.svg'; 
chesslib.board.images.PbSrc = 'mimes/WhitePawnBlackField.svg'; 
chesslib.board.images.rwSrc = 'mimes/BlackRookWhiteField.svg'; 
chesslib.board.images.rbSrc = 'mimes/BlackRookBlackField.svg'; 
chesslib.board.images.RwSrc = 'mimes/WhiteRookWhiteField.svg'; 
chesslib.board.images.RbSrc = 'mimes/WhiteRookBlackField.svg'; 
chesslib.board.images.nwSrc = 'mimes/BlackKnightWhiteField.svg'; 
chesslib.board.images.nbSrc = 'mimes/BlackKnightBlackField.svg'; 
chesslib.board.images.NwSrc = 'mimes/WhiteKnightWhiteField.svg'; 
chesslib.board.images.NbSrc = 'mimes/WhiteKnightBlackField.svg'; 
chesslib.board.images.bwSrc = 'mimes/BlackBishopWhiteField.svg'; 
chesslib.board.images.bbSrc = 'mimes/BlackBishopBlackField.svg'; 
chesslib.board.images.BwSrc = 'mimes/WhiteBishopWhiteField.svg'; 
chesslib.board.images.BbSrc = 'mimes/WhiteBishopBlackField.svg'; 
chesslib.board.images.qwSrc = 'mimes/BlackQueenWhiteField.svg'; 
chesslib.board.images.qbSrc = 'mimes/BlackQueenBlackField.svg'; 
chesslib.board.images.QwSrc = 'mimes/WhiteQueenWhiteField.svg'; 
chesslib.board.images.QbSrc = 'mimes/WhiteQueenBlackField.svg'; 
chesslib.board.images.kwSrc = 'mimes/BlackKingWhiteField.svg'; 
chesslib.board.images.kbSrc = 'mimes/BlackKingBlackField.svg'; 
chesslib.board.images.KwSrc = 'mimes/WhiteKingWhiteField.svg'; 
chesslib.board.images.KbSrc = 'mimes/WhiteKingBlackField.svg'; 
chesslib.board.codeSnippets = {};

chesslib.board.codeSnippets.onClick = function (e) {
	var field = this.id.split('_');
	field = field[field.length-1];
	var board = this.parentNode.parentNode.chess;
	if(board.move){ //the user clicked something already
		for (var m in board.move) {
			if (!(board.move.hasOwnProperty(m))) continue;
			var move = m;
		};
		if (board.move.hasOwnProperty(field)) { //the user wants to do take back the started move
			for (var i in board.move[field]) {
				if (!(board.move[field].hasOwnProperty(i))) continue;
				if (!(board.fields.hasOwnProperty(board.move[field][i]))) continue;
				board.fields[board.move[field][i]].removeEventListener('click',chesslib.board.codeSnippets.onClick,false);
				board.fields[board.move[field][i]].classList.remove('chesshighlight');
			};
			this.classList.remove('chesshighlight');
			board.move = null;
		} else { //the user chooses the field to move to or clicked on a different start field
			if (this.classList.contains('chesshighlight')) {  //clicked the field to move to
				var promo = false;
				if((board.move[move].length === 1)&&(board.move[move][0].indexOf('?') === 2)) { //promotion
					promo = true;
				};
				board.move[move] = field;
				var changes = {};
				changes[field] = board.fields[move].chess.figure;
				changes[move] = '-';
				//special treatment enpassant
				
				board.setFigures(changes);
				for (var f in board.fields){
					if(!(board.fields.hasOwnProperty(f))) continue;
					board.fields[f].removeEventListener('click', chesslib.board.codeSnippets.onClick,false);
					board.fields[f].classList.remove('chesshighlight');
				};
				if( promo ){
					board.promotionPopup.style.visibility = 'visible';
				} else {
					if (board.callThisAfterMove)
						setTimeout(board.callThisAfterMove.call(board), 0);
				}
			} else { //new field selected
				for (var f in board.fields) {
					if (!(board.fields.hasOwnProperty(f))) continue;
					board.fields[f].classList.remove('chesshighlight');
				};
				for (var p in board._possibleMoves[move]) {
					if (!(board._possibleMoves[move].hasOwnProperty(p))) continue;
					board.fields[board._possibleMoves[move][p]].removeEventListener('click', chesslib.board.codeSnippets.onClick,false);
				};
				board.move = {};
				board.move[field] = board._possibleMoves[field];
				board.fields[field].classList.add('chesshighlight');
				for (var h in board.move[field]) {
					if(!(board.move[field].hasOwnProperty(h))) continue;
					board.fields[board.move[field][h]].classList.add('chesshighlight');
					board.fields[board.move[field][h]].addEventListener('click', chesslib.board.codeSnippets.onClick,false);
				};
			};
		};
	} else { //the user starts clicking
		board.move = {};
		board.move[field] = board._possibleMoves[field];
		board.fields[field].classList.add('chesshighlight');
		for (var h in board.move[field]) {
			if(!(board.move[field].hasOwnProperty(h))) continue;
			//the slice(0,2) is necessary for moves containing a "?"
			//indicating a promotion	
			board.fields[board.move[field][h].slice(0,2)].classList.add('chesshighlight');
			board.fields[board.move[field][h].slice(0,2)].addEventListener('click', chesslib.board.codeSnippets.onClick,false);
		};
	};
};

chesslib.board.codeSnippets.doThisAfterUserMovedOnBoardReferenceImp = function(pm){
	
};

chesslib.board.codeSnippets.setPossibleMoves = function(movesList, func){
	//a function that enables moves via mouse clicks.
	//the moveslist is an object with properties named like fields ("e4") marking the
	//start field of the move. The value is an array
	// with possible target fields of the figure placed on start field.
	// The board is stupid and has no clue of chess
	// hence you can specify a function invoked on the board
	// after the user moved in order to complete castling
	// or delete the pawn before the en passant field.
	// The promotion is handled by the function itself since it is key to describe
	// the complete move of the user.
	// a possible part of the movesList is 
	// {"e7":["e8?"]} Where the ? tells the board to ask the user which promotion
	// to perform
	this._possibleMoves = {};
	this.callThisAfterMove = func;
	for(var fromField in movesList) {
		if(!(movesList.hasOwnProperty(fromField))) continue;
		if(!(this.fields.hasOwnProperty(fromField))) continue;
		if(!(movesList[fromField] instanceof Array)) continue;
		this._possibleMoves[fromField] = movesList[fromField];
		this.fields[fromField].addEventListener('click', chesslib.board.codeSnippets.onClick,false);
	};

};

chesslib.board.codeSnippets.setFigures = function(pl) {
	if (typeof pl !== 'object') return;
	for (var f in pl) {
		if (!(pl.hasOwnProperty(f))) continue;
		if (!(this.fields.hasOwnProperty(f))) continue;
		if ('-kKqQbBnNrRpP'.indexOf(pl[f]) === -1) continue;
		if (pl[f] === '-') {
			var figureSrc = 'empty';
			delete this.fields[f].chess.figure;
		} else {
			var color = this.fields[f].classList.contains("whitefield")?"w":"b";
			var figureSrc = pl[f] + color + "Src";
			this.fields[f].chess.figure = pl[f];
		};
		this.fields[f].src = chesslib.board.images[figureSrc];
	};
};

chesslib.board.createBoardInElement = function (elem, blackTop){
// deletes the content of elem and replaces it with a div that holds the chess 
// board. This div has the following additional functions:
// setFigures (o) where o is an object with the figures to be changed on the board
// like {e4:k, f5:P, h1:-} which would place a black king on e4 a white pawn 
// on f5 and clear the field h1 leaving the rest of the board untouched
	
	var nodeToInsert, i, j, imageNodeField, rank, white_field, boardNode;
	blackTop = blackTop || false;
	var letters	= blackTop ? ['a','b','c','d','e','f','g','h'] : ['h','g','f','e','d','c','b','a'];
	if (!elem instanceof HTMLElement) return false;
	elem.innerHTML = "";
	boardNode = document.createElement('div');
//	boardNode = object.Create(chesslib.board.prototypeBoardDiv);
	boardNode.id = elem.id + "_chessboard";
	boardNode.classList.add('chessboard');
	boardNode.chess = {};
	boardNode.chess.fields = {};  //the nodes that hold the images
	boardNode.chess.move = null;  //the move the user wants to do in the current position
	boardNode.chess._possibleMoves = null;  //the possible moves handed over and filtered; should be set by corresponding function
	boardNode.chess.setFigures = chesslib.board.codeSnippets.setFigures;
	boardNode.chess.setPossibleMoves = chesslib.board.codeSnippets.setPossibleMoves;
	chesslib.board.boards.push(boardNode);
	white_field = true;
	for (i=0; i<8; i++) {
		rank = blackTop ? 8 - i : i+1;
		nodeToInsert = document.createElement('div');
		nodeToInsert.id = boardNode.id + '_boardrank_' + rank;
		nodeToInsert.classList.add('chessboard_rank');
		for (j=0;j<8;j++){
			imageNodeField = chesslib.board.images.emptyImageTag.cloneNode();
			imageNodeField.style.width = "12.5%";
			imageNodeField.id = boardNode.id + "_field_" + letters[j] + rank;
			imageNodeField.classList.add(white_field ? 'whitefield' : 'blackfield');
			imageNodeField.classList.add('chessboard_field');
			imageNodeField.chess = {};
			boardNode.chess.fields[letters[j] + rank] = imageNodeField; 
			white_field = !white_field;
			nodeToInsert.appendChild(imageNodeField);
		};
		boardNode.appendChild(nodeToInsert);
		white_field = !white_field;
	};
	//promo popup declared here
	var promoNode = document.createElement('div');
	promoNode.id = boardNode.id + '_promoPopup';
	promoNode.classList.add("promotionOverlay");

	var divNode1 = document.createElement('div');
	var divNode2 = document.createElement('div');
	var divNode3 = document.createElement('div');
	
	promoNode.appendChild(divNode1);
	promoNode.appendChild(divNode2);
	promoNode.appendChild(divNode3);
	
	var funcOnClick = function(e){
		var short = this.parentNode.parentNode.parentNode.chess;
		short.move.promotion = 
			this.chess.promotion;
		this.parentNode.parentNode.style.visibility = 'hidden';
		if (short.callThisAfterMove)
			setTimeout(short.callThisAfterMove.call(short), 0);
	};
	
	var imgR = document.createElement('img');
	imgR.src = chesslib.board.images.RwSrc;
	imgR.chess= {};
	imgR.chess.promotion = 'R';
	imgR.onclick = funcOnClick;
	divNode2.appendChild(imgR);
	var imgN = document.createElement('img');
	imgN.src = chesslib.board.images.NwSrc;
	imgN.chess= {};
	imgN.chess.promotion = 'N';
	imgN.onclick = funcOnClick;
	divNode2.appendChild(imgN);
	var imgB = document.createElement('img');
	imgB.src = chesslib.board.images.BwSrc;
	imgB.chess= {};
	imgB.chess.promotion = 'B';
	imgB.onclick = funcOnClick;
	divNode2.appendChild(imgB);
	var imgQ = document.createElement('img');
	imgQ.src = chesslib.board.images.QwSrc;
	imgQ.chess= {};
	imgQ.chess.promotion = 'Q';
	imgQ.onclick = funcOnClick;
	divNode2.appendChild(imgQ);

	boardNode.appendChild(promoNode);
	boardNode.chess.promotionPopup = promoNode;
	elem.appendChild(boardNode);
	return boardNode;
};